package com.glela.platform.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONObject;
import com.glela.cache.redis.RedisKeys;
import com.glela.cache.redis.RedisUtil;
import com.glela.common.exception.PlatformException;
import com.glela.common.util.DateUtil;
import com.glela.common.util.DateUtils;
import com.glela.common.util.StringUtil;
import com.glela.platform.constant.ErrorEnum;
import com.glela.platform.mapper.GivePromotionHistoryMapper;
import com.glela.platform.mapper.GivePromotionListMapper;
import com.glela.platform.mapper.PromotionDetailMapper;
import com.glela.platform.mapper.PromotionMapper;
import com.glela.platform.mapper.TalentJobMapper;
import com.glela.platform.mapper.UserMapper;
import com.glela.platform.mapper.UserPromotionMapper;
import com.glela.platform.model.BaseRestrictions;
import com.glela.platform.model.GivePromotionHistory;
import com.glela.platform.model.GivePromotionList;
import com.glela.platform.model.Promotion;
import com.glela.platform.model.PromotionDetail;
import com.glela.platform.model.TalentJob;
import com.glela.platform.model.User;
import com.glela.platform.model.UserPromotion;
import com.glela.platform.model.response.ResponseBaseModel;
import com.glela.platform.model.response.ResponseCouponModel;
import com.glela.platform.model.response.ResponseResultModel;
import com.glela.platform.service.BaseRestrictionsService;
import com.glela.platform.service.PromotionService;

@Service("promotionService")
@Scope("singleton")
public class PromotionServiceImpl implements PromotionService {
	private static Logger logger	 = LoggerFactory.getLogger(PromotionService.class);
	@Autowired
	private GivePromotionListMapper givePromotionListMapper;
	@Autowired
	private GivePromotionHistoryMapper givePromotionHistoryMapper;
	@Autowired
	private PromotionMapper promotionMapper;
	@Autowired
	private BaseRestrictionsService baseRestrictionsService;
	@Autowired
	private RedisUtil redisUtil;
	@Autowired
	private UserMapper userMapper;
	@Autowired
	private TalentJobMapper talentJobMapper;
	@Autowired
	private PromotionDetailMapper promotionDetailMapper;
	@Autowired
	private UserPromotionMapper userPromotionMapper;
	
	/**
	 * 赠送优惠券礼包
	 */
	@Override
	public ResponseEntity<?> givePromotionPackage(Long giver, Long accepter,Long promotionId) {
		// 校验Redis是否存在赠送优惠券礼包指令值
		String key = RedisKeys.GIVE_PROMOTION_PACKAGE + giver + "-" + accepter + "-" + promotionId;
		String redisCache = this.redisUtil.get(key);
		if (StringUtil.isEmpty(redisCache)) {// redis没有缓存
			redisUtil.setex(key, 120, "当前" + giver + "正在给" + accepter + "赠送礼包" + promotionId + ".");
		} else {// redis有缓存，说明当前正在赠送礼包，并发了，提示赠送成功
			return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C10000), HttpStatus.OK);
		}
		// 赠送优惠券礼包
		Promotion promotion = this.promotionMapper.selectByPrimaryKey(promotionId.intValue());
		if (promotion == null) {
			return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C43001), HttpStatus.OK);
		}
		// 优惠券过期时间
		Integer expirationDay = this.baseRestrictionsService.getBaseRestrictionsForCache("expiration_day").getExperience();
		User giverUser = this.userMapper.selectByPrimaryKey(giver);
		if (giverUser == null) {
			return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C43005), HttpStatus.OK);
		}
		User accepterUser = this.userMapper.selectByPrimaryKey(accepter);
		if (accepterUser == null) {
			return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C43006), HttpStatus.OK);
		}
		String jobNo = "0";
		TalentJob talentJob = talentJobMapper.selectTalentJobByUserId(giver);
		if (talentJob != null) {
			jobNo = talentJob.getJobNo();
		}
		Date nowDate = DateUtil.toDate(System.currentTimeMillis());
		// 优惠券礼包赠送主表
		GivePromotionList givePromotionList = new GivePromotionList();
		givePromotionList.setTearchUserId(giver.intValue());
		givePromotionList.setTearchJobNo(jobNo);
		givePromotionList.setGiveTime(nowDate);
		givePromotionList.setPromotionId(promotionId.intValue());
		givePromotionList.setAdminUserId(0);
		givePromotionList.setNums(1);
		int i = this.givePromotionListMapper.insertAndGetId(givePromotionList);
		if (i < 1) {
			return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C43002), HttpStatus.OK);
		}
		// 优惠券礼包赠送附表
		GivePromotionHistory givePromotionHistory = new GivePromotionHistory();
		givePromotionHistory.setTearchUserId(giver);
		givePromotionHistory.setTearchJobNo(jobNo);
		givePromotionHistory.setAdminUserId(0L);
		givePromotionHistory.setUserId(accepter);
		givePromotionHistory.setUserRoleId(Long.valueOf(accepterUser.getRoleId()));
		givePromotionHistory.setPromotionId(promotionId);
		givePromotionHistory.setGiveTime(nowDate);
		givePromotionHistory.setExpirationTime(DateUtil.parse(DateUtil.getFewDays(expirationDay)));
		givePromotionHistory.setStatus(1);
		givePromotionHistory.setpId(givePromotionList.getId());
		int j = this.givePromotionHistoryMapper.insertSelective(givePromotionHistory);
		if (j < 1) {
			return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C43002), HttpStatus.OK);
		}
		// 礼包赠送完毕后，删除Redis缓存，不然下次提交请求会被拒绝
		this.redisUtil.del(key);
		return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C10000), HttpStatus.OK);
	}
	
	/**
	 * 预加载可领优惠券礼包
	 */
	@Override
	public ResponseEntity<?> preLoadPromotionPackages(Long accepter) {
		List<Map<String, Object>> teacherGivers = this.givePromotionHistoryMapper.selectGives(accepter);
		Map<String, Object> result = new HashMap<String, Object>();
		if (CollectionUtils.isEmpty(teacherGivers)) {
			result.put("isHasPP", "0");// 不存在可领取的礼包
			List<Map<String, Object>> promotionInfo = new ArrayList<Map<String,Object>>();
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("giverName", "");// 赠送人的名称
			map.put("promotionPackages", new ArrayList<GivePromotionHistory>());// 礼包明细
			promotionInfo.add(map);
			result.put("promotionInfo", promotionInfo);
		} else {
			List<Map<String, Object>> promotionInfo = new ArrayList<Map<String,Object>>();
			for (Map<String, Object> tgph : teacherGivers){
				List<Map<String,Object>> promotionPackages = this.givePromotionHistoryMapper.selectGivePromotionPackages(Long.valueOf(tgph.get("giverId").toString()),accepter);
				if (!CollectionUtils.isEmpty(promotionPackages)) {
					Map<String, Object> map = new HashMap<String, Object>();
					map.put("giverName", tgph.get("giverName").toString());// 赠送人的名称
					map.put("promotionPackages", promotionPackages);// 礼包明细
					promotionInfo.add(map);
				}
			}
			if (CollectionUtils.isEmpty(promotionInfo)) {
				result.put("isHasPP", "0");// 不存在可领取的礼包
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("giverName", "");// 赠送人的名称
				map.put("promotionPackages", new ArrayList<GivePromotionHistory>());// 礼包明细
				promotionInfo.add(map);
			} else {
				result.put("isHasPP", "1");// 存在可领取的礼包
			}
			result.put("promotionInfo", promotionInfo);
		}
		return new ResponseEntity<>(new ResponseResultModel<>(result), HttpStatus.OK);
	}
	
	/**
	 * 领取优惠券礼包
	 */
	@Override
	public ResponseEntity<?> addPromotionPackages(Long accepter) {
		// 校验Redis是否存在领取优惠券礼包指令值
		String key = RedisKeys.GIVE_PROMOTION_PACKAGE + accepter;
		String redisCache = this.redisUtil.get(key);
		if (StringUtil.isEmpty(redisCache)) {// redis没有缓存
			redisUtil.setex(key, 120, "当前" + accepter + "正在领取礼包.");
		} else {// redis有缓存，说明当前正在领取礼包，并发了，提示领取成功
			return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C10000), HttpStatus.OK);
		}
		List<Map<String, Object>> result = new ArrayList<Map<String,Object>>();
		List<GivePromotionHistory> gphList = this.givePromotionHistoryMapper.selectByAccepter(accepter);
		if (!CollectionUtils.isEmpty(gphList)) {
			// 领取优惠券礼包的时间
			Date getTime = DateUtil.toDate(System.currentTimeMillis());
			for(GivePromotionHistory gph : gphList){
				Map<String, Object> pMap = new HashMap<String, Object>();
				Promotion promotion = this.promotionMapper.selectByPrimaryKey(gph.getPromotionId().intValue());
				if (promotion == null) {
					continue;
				}
				pMap.put("promotionName", promotion.getName() == null ? "" : promotion.getName());
				pMap.put("promotionDescripe", promotion.getDescripe() == null ? "" : promotion.getDescripe());
				List<ResponseCouponModel> promotionDetails = new ArrayList<ResponseCouponModel>();
				List<PromotionDetail> listPromotionDetail = this.promotionDetailMapper.selectPromotionDetailByPromotionId(gph.getPromotionId().intValue());
				for (PromotionDetail promotionDetail : listPromotionDetail) {
					// 赠送多张优惠，存到用户优惠券时，需要拆开后在保存
					for(int i = 0 ; i < promotionDetail.getPromotionDetailNumber() ; i++){
						UserPromotion userPromotion = new UserPromotion();
						userPromotion.setPromotionId(promotionDetail.getPromotionId());
						userPromotion.setPromotionDetailId(promotionDetail.getId());
						userPromotion.setType(promotionDetail.getType());
						userPromotion.setPromotionDetailName(promotionDetail.getPromotionDetailName());
						userPromotion.setUserId(accepter);
						userPromotion.setBrandId(promotionDetail.getBrandId());
						userPromotion.setGoodId(promotionDetail.getGoodId());
						userPromotion.setLimited(promotionDetail.getLimited());
						userPromotion.setIsDiscount(promotionDetail.getIsDiscount());
						userPromotion.setAmount(promotionDetail.getAmount());
						if (promotionDetail.getLimitDay() == 0) {// 没有配置限制过期时间
							userPromotion.setEffectiveTime(promotionDetail.getEffectiveTime());
							userPromotion.setExpirationTime(promotionDetail.getExpirationTime());
						} else {// 设置了N天后过期
							String nowTime = DateUtil.getNow();// 当前时间
							// 当前时间大于等于失效时间
							if (DateUtil.parse(nowTime).getTime() >= DateUtil.parse(promotionDetail.getExpirationTime()).getTime()) {
								userPromotion.setEffectiveTime(promotionDetail.getEffectiveTime());
								userPromotion.setExpirationTime(promotionDetail.getExpirationTime());
							} else if (DateUtil.parse(nowTime).getTime() >= DateUtil.parse(promotionDetail.getEffectiveTime()).getTime()) {// 当前时间大于等于生效时间
								userPromotion.setEffectiveTime(nowTime);
								// 当前时间N天后的时间（失效时间）
								String afterNowNDaysTime = DateUtil.getFewDays(promotionDetail.getLimitDay());
								// 将失效时间改成当天时间23点59分59秒
								afterNowNDaysTime = DateUtil.toDateStr(DateUtil.parse(afterNowNDaysTime)) + " 23:59:59";
								// 当前N天后的时间大于等于失效时间
								if (DateUtil.parse(afterNowNDaysTime).getTime() >= DateUtil.parse(promotionDetail.getExpirationTime()).getTime()) {
									userPromotion.setExpirationTime(promotionDetail.getExpirationTime());
								} else {// 当前N天后的时间小于失效时间
									userPromotion.setExpirationTime(afterNowNDaysTime);
								}
							} else {// 当前时间小于优惠券生效时间
								userPromotion.setEffectiveTime(promotionDetail.getEffectiveTime());
								// 生效时间N天后的日期（失效时间）
								String afterEffectiveTimeNDaysTime = DateUtil.getFewDays(DateUtil.parse(promotionDetail.getEffectiveTime()),promotionDetail.getLimitDay());
								// 将失效时间改成当天时间23点59分59秒
								afterEffectiveTimeNDaysTime = DateUtil.toDateStr(DateUtil.parse(afterEffectiveTimeNDaysTime)) + " 23:59:59";
								// 失效时间大于等于生效时间N天后的时间
								if (DateUtil.parse(promotionDetail.getExpirationTime()).getTime() >= DateUtil.parse(afterEffectiveTimeNDaysTime).getTime()) {
									userPromotion.setExpirationTime(afterEffectiveTimeNDaysTime);
								} else {// 失效时间小于生效时间N天后的时间
									userPromotion.setExpirationTime(promotionDetail.getExpirationTime());
								}
							}
						}
						userPromotion.setPromotionNumber(1);
						userPromotion.setTargetSelfType(promotionDetail.getTargetSelfType());
						userPromotion.setDiscount(promotionDetail.getDiscount());
						this.userPromotionMapper.insertUserPromotion(userPromotion);
						promotionDetail.setEffectiveTime(userPromotion.getEffectiveTime());
						promotionDetail.setExpirationTime(userPromotion.getExpirationTime());
					}
					promotionDetails.add(new ResponseCouponModel(promotionDetail));
				}
				// 没有可以领取的礼包信息，将礼包作废
				if (promotionDetails.size() == 0) {
					gph.setStatus(0);
				} else {
					pMap.put("promotionDetails", promotionDetails);
					result.add(pMap);
				}
				gph.setGetTime(getTime);
				// 更新领取时间
				int i = this.givePromotionHistoryMapper.updateByPrimaryKeySelective(gph);
				if (i < 1) {
					throw new PlatformException(ErrorEnum.C43004, ErrorEnum.C43004.getMessage());
				}
			}
		}
		// 礼包领取完毕后，删除Redis缓存，不然下次提交请求会被拒绝
		this.redisUtil.del(key);
		// 没有可领取的礼包信息
		if (result.size() == 0) {
			return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C43007), HttpStatus.OK);
		}
		return new ResponseEntity<>(new ResponseResultModel<>(result), HttpStatus.OK);
	}

	public void addOpenStorePromotionPackages(String orderSn,Long userID,Integer userRole) throws PlatformException {
		BaseRestrictions new_shop_promotion_id=baseRestrictionsService.getBaseRestrictionsForCache("new_shop_promotion_id");
		BaseRestrictions xz_jj=baseRestrictionsService.getBaseRestrictionsForCache("xz_jj");
		BaseRestrictions  givenPromotionHistory=baseRestrictionsService.getBaseRestrictionsForCache("givenPromotionHistory");
		int givenPromotionHistoryDay=givenPromotionHistory==null?5:givenPromotionHistory.getExperience();//过期天数 默认5天
		if(xz_jj==null){//未找到配置项
			throw new PlatformException("校妆姐姐配置项未找到");
		}
		TalentJob JobNo=talentJobMapper.selectTalentJobByUserId(xz_jj.getExperience());
		if(JobNo==null||org.apache.commons.lang3.StringUtils.isBlank(JobNo.getJobNo())){//未找到配置项
			throw new PlatformException("未找到相应的讲师编号:讲师ID"+xz_jj.getExperience());
		}
		if(new_shop_promotion_id!=null&&new_shop_promotion_id.getStatus()==1
				&&StringUtils.isBlank(redisUtil.get(RedisKeys.YG_ORDER_OPENSTORE_PROMOTION+orderSn))){//订单号为空 没有送过 开始送
			GivePromotionList promotion=new GivePromotionList();
			promotion.setAdminUserId(1);
			promotion.setNums(1);
			promotion.setPromotionId(new_shop_promotion_id.getRestrictions());
			promotion.setTearchJobNo(JobNo.getJobNo());
			promotion.setTearchUserId(xz_jj.getExperience());
			promotion.setGiveTime(new Date());
			if(givePromotionListMapper.insertSelective(promotion)<1){
				throw new PlatformException("GivePromotionList:开店插入礼包失败");
			}
			GivePromotionHistory givePromotionHistory=new GivePromotionHistory();//礼包发放明细信息
			givePromotionHistory.setTearchUserId(promotion.getTearchUserId().longValue());
			givePromotionHistory.setTearchJobNo(promotion.getTearchJobNo());
			givePromotionHistory.setPromotionId(promotion.getPromotionId().longValue());
			givePromotionHistory.setUserId(userID);
			givePromotionHistory.setUserRoleId(userRole.longValue());
			givePromotionHistory.setGiveTime(promotion.getGiveTime());
			givePromotionHistory.setAdminUserId(promotion.getAdminUserId().longValue());
			givePromotionHistory.setExpirationTime(DateUtils.addDay(promotion.getGiveTime(),givenPromotionHistoryDay));
			givePromotionHistory.setStatus(1);
			givePromotionHistory.setpId(promotion.getId());
			if(givePromotionHistoryMapper.insertSelective(givePromotionHistory)<1){
				throw new PlatformException("GivePromotionList:礼包生成明细失败");
			}
			try {
				Map<String,String> mapJSON=new HashMap<String,String>();
				mapJSON.put("promotion", JSONObject.toJSONString(promotion).toString());
				mapJSON.put("givePromotionHistory", JSONObject.toJSONString(givePromotionHistory).toString());
				redisUtil.set(RedisKeys.YG_ORDER_OPENSTORE_PROMOTION+orderSn,mapJSON.toString(), 60*1*60*24*15);//记录一下是否送了优惠券 记录保存包个月	
			} catch (Exception e) {
				logger.error("addOpenStorePromotionPackages 添加缓存出错{},开始重新添加",e.getMessage());
				redisUtil.set(RedisKeys.YG_ORDER_OPENSTORE_PROMOTION+orderSn,givePromotionHistory.toString()+promotion.toString(), 60*1*60*24*15);//记录一下是否送了优惠券	
			}
		}
	}
}
